package com.ruibang.glass.material.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruibang.glass.common.constants.RedisKey;
import com.ruibang.glass.common.domain.camunda.BpmProcessInstanceStatus;
import com.ruibang.glass.common.utils.ApproveUserNameUtils;
import com.ruibang.glass.material.constant.Constants;
import com.ruibang.glass.material.constant.MaterialWareHouseCode;
import com.ruibang.glass.material.constant.MaterialWareHouseInTableNameCode;
import com.ruibang.glass.material.domain.req.MaterialDullnessReq;
import com.ruibang.glass.material.domain.req.MaterialRQDullnessReq;
import com.ruibang.glass.material.dto.MaterialDullnessDTO;
import com.ruibang.glass.material.dto.MaterialRqDullnessDTO;
import com.ruibang.glass.material.entity.*;
import com.ruibang.glass.material.entity.bcp.MaterialBcpProductsInInfo;
import com.ruibang.glass.material.entity.bcp.MaterialBcpProductsOut;
import com.ruibang.glass.material.entity.cp.MaterialCPProductsInInfo;
import com.ruibang.glass.material.entity.cp.MaterialCPProductsOut;
import com.ruibang.glass.material.entity.ycl.MaterialManagementInventory;
import com.ruibang.glass.material.feign.CamundaApi;
import com.ruibang.glass.material.mapper.GMaterialALLOutboundManagementMapper;
import com.ruibang.glass.material.mapper.MaterialAllOutboundItemMapper;
import com.ruibang.glass.material.mapper.MaterialCpBcpItemsMapper;
import com.ruibang.glass.material.mapper.MaterialInventoryItemMapper;
import com.ruibang.glass.material.mapper.bcp.MaterialBcpProductsInInfoMapper;
import com.ruibang.glass.material.mapper.bcp.MaterialBcpProductsOutMapper;
import com.ruibang.glass.material.mapper.cp.MaterialCPProductsInInfoMapper;
import com.ruibang.glass.material.mapper.cp.MaterialCPProductsOutMapper;
import com.ruibang.glass.material.service.GMaterialALLInventoryManagementService;
import com.ruibang.glass.material.service.MaterialDullnessService;
import com.ruibang.glass.material.service.MaterialWarehouseInfoService;
import com.teaming.cloud.framework2.autoconfigure.redis.RedisSingleService;
import com.teaming.cloud.framework2.common.constant.CommonConstant;
import com.teaming.cloud.framework2.common.model.ResultBody;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 呆滞统计
 * </p>
 *
 * @author mameng
 * @since 2024-03-30
 */
@Service
public class MaterialDullnessServiceImpl implements MaterialDullnessService {
    @Autowired
    private GMaterialALLOutboundManagementMapper materialALLOutboundManagementMapper;
    @Autowired
    private CommonService commonService;
    @Autowired
    private RedisSingleService redisService;

    @Autowired
    private CamundaApi camundaApi;

    @Autowired
    private MaterialBcpProductsOutMapper materialBcpProductsOutMapper;

    @Autowired
    private MaterialBcpProductsInInfoMapper materialBcpProductsInInfoMapper;
    @Autowired
    private MaterialCPProductsOutMapper materialCpProductsOutMapper;

    @Autowired
    private MaterialCPProductsInInfoMapper materialCPProductsInInfoMapper;

    @Autowired
    private MaterialAllOutboundItemMapper materialAllOutboundItemMapper;

    @Autowired
    private MaterialInventoryItemMapper materialInventoryItemMapper;

    @Autowired
    private MaterialCpBcpItemsMapper materialCpBcpItemsMapper;

    @Autowired
    private MaterialWarehouseInfoService materialWarehouseInfoService;

    @Autowired
    private GMaterialALLInventoryManagementService materialInventoryManagementService;

    @Override
    public Page<MaterialManagementInventory> getDullnessPage(MaterialDullnessReq materialDullnessReq) {
        List<String> collect1 = new ArrayList<>();
        List<String> collect2 = new ArrayList<>();
        List<String> allIds = new ArrayList<>();
        LambdaQueryWrapper<MaterialAllOutboundItem> materialOutWrapper = Wrappers.<MaterialAllOutboundItem>lambdaQuery();
        if (StringUtils.isNotEmpty(materialDullnessReq.getItemCode())) {
            materialOutWrapper.like(MaterialAllOutboundItem::getItemCode, materialDullnessReq.getItemCode());
        }
        if (StringUtils.isNotEmpty(materialDullnessReq.getItemName())) {
            materialOutWrapper.like(MaterialAllOutboundItem::getItemName, materialDullnessReq.getItemName());
        }

        if (StringUtils.isNotEmpty(materialDullnessReq.getItemCode()) || StringUtils.isNotEmpty(materialDullnessReq.getItemName())) {
            List<MaterialAllOutboundItem> materialAllOutboundItems = materialAllOutboundItemMapper.selectList(materialOutWrapper);
            collect1 = materialAllOutboundItems.stream().map(MaterialAllOutboundItem::getOutAllId).distinct().collect(Collectors.toList());
            allIds.addAll(collect1);
        }

        LambdaQueryWrapper<MaterialInventoryItem> materialInventoryItemWrapper = Wrappers.<MaterialInventoryItem>lambdaQuery();
        if (StringUtils.isNotEmpty(materialDullnessReq.getItemCode())) {
            materialInventoryItemWrapper.like(MaterialInventoryItem::getItemCode, materialDullnessReq.getItemCode());
        }
        if (StringUtils.isNotEmpty(materialDullnessReq.getItemName())) {
            materialInventoryItemWrapper.like(MaterialInventoryItem::getItemName, materialDullnessReq.getItemName());
        }

        if (StringUtils.isNotEmpty(materialDullnessReq.getItemCode()) || StringUtils.isNotEmpty(materialDullnessReq.getItemName())) {
            List<MaterialInventoryItem> materialInventoryItems = materialInventoryItemMapper.selectList(materialInventoryItemWrapper);
            collect2 = materialInventoryItems.stream().map(MaterialInventoryItem::getInventoryNumber).distinct().collect(Collectors.toList());
            allIds.addAll(collect2);
        }
        if (StringUtils.isNotEmpty(materialDullnessReq.getItemCode()) || StringUtils.isNotEmpty(materialDullnessReq.getItemName())) {
            if (CollectionUtils.isEmpty(collect1) && CollectionUtils.isEmpty(collect2)) {
                Page<MaterialManagementInventory> page = new Page<>();
                return page;
            }
        }

        materialDullnessReq.setIds(allIds);

        MaterialWarehouseInfo one = materialWarehouseInfoService.getOne(Wrappers.<MaterialWarehouseInfo>lambdaQuery().isNotNull(MaterialWarehouseInfo::getProcessStalePeriod).gt(MaterialWarehouseInfo::getProcessStalePeriod, Constants.ZERO_INT).eq(MaterialWarehouseInfo::getWarehouseCode, materialDullnessReq.getWarehouseCode()).last("limit 1"));
        if (one == null) {
            Page<MaterialManagementInventory> page = new Page<>();
            return page;
        }
        materialDullnessReq.setDullnessDay(one.getProcessStalePeriod());
        for (MaterialWareHouseInTableNameCode ele : MaterialWareHouseInTableNameCode.values()) {
            if (materialDullnessReq.getWarehouseCode().equals(ele.getCode())) {
                materialDullnessReq.setTableName(ele.getMsg());
                Page<MaterialManagementInventory> page = materialALLOutboundManagementMapper.getAllDullnessList(new Page<MaterialManagementInventory>(materialDullnessReq.getPageNo(), materialDullnessReq.getPageSize()), materialDullnessReq);
                Map<Object, Object> userMap = redisService.hmget(RedisKey.USER_GROUP_TYPE);
                if (CollectionUtils.isEmpty(page.getRecords())) {
                    return page;
                }
                // 获取出入库物料名称 编号 规格型号
                List<String> idList = page.getRecords().stream().map(MaterialManagementInventory::getId).collect(Collectors.toList());
                List<MaterialAllOutboundItem> materialAllOutboundItems = materialAllOutboundItemMapper.selectList(Wrappers.<MaterialAllOutboundItem>lambdaQuery().in(MaterialAllOutboundItem::getOutAllId, idList));
                List<String> numberList = page.getRecords().stream().map(MaterialManagementInventory::getNumber).collect(Collectors.toList());
                List<MaterialInventoryItem> materialInventoryItems = materialInventoryItemMapper.selectList(Wrappers.<MaterialInventoryItem>lambdaQuery().in(MaterialInventoryItem::getInventoryNumber, numberList));

                Map<String, List<MaterialInventoryItem>> itemMap = null;
                if (CollectionUtils.isNotEmpty(materialInventoryItems)) {
                    itemMap = materialInventoryItems.stream().collect(Collectors.groupingBy(MaterialInventoryItem::getInventoryNumber));
                }
                Map<String, List<MaterialAllOutboundItem>> outBoundItemMap = null;
                if (CollectionUtils.isNotEmpty(materialAllOutboundItems)) {
                    outBoundItemMap = materialAllOutboundItems.stream().collect(Collectors.groupingBy(MaterialAllOutboundItem::getOutAllId));
                }

                List<String> businessKeys = page.getRecords().stream().map(MaterialManagementInventory::getId).collect(Collectors.toList());
                Map<String, BpmProcessInstanceStatus> processMap = null;
                //获取业务流程状态
                ResultBody<List<BpmProcessInstanceStatus>> resultBody = camundaApi.queryProcessInstanceStatus(businessKeys);
                if (resultBody != null && CollectionUtils.isNotEmpty(resultBody.getData())) {
                    processMap = resultBody.getData().stream().collect(Collectors.toMap(bp -> bp.getBusinessKey(), bp -> bp, (bp1, bp2) -> bp1));
                }

                for (MaterialManagementInventory materialManagementInventory : page.getRecords()) {
                    if (itemMap != null) {
                        List<MaterialInventoryItem> items = itemMap.get(materialManagementInventory.getNumber());
                        if (CollectionUtils.isNotEmpty(items)) {
                            String itemName = items.stream().map(i -> i.getItemName()).collect(Collectors.toList()).stream()
                                    .collect(Collectors.joining(CommonConstant.SpecialSign.COMMA.getName()));
                            materialManagementInventory.setItemName(itemName);
                            String specification = items.stream().map(i -> i.getSpecificationModel()).collect(Collectors.toList()).stream()
                                    .collect(Collectors.joining(CommonConstant.SpecialSign.COMMA.getName()));
                            if (StringUtils.isNotEmpty(specification) && !StringUtils.equals(specification, "null")) {
                                materialManagementInventory.setSpecification(specification);
                            }

                            String itemCode = items.stream().map(i -> i.getItemCode()).collect(Collectors.toList()).stream()
                                    .collect(Collectors.joining(CommonConstant.SpecialSign.COMMA.getName()));
                            materialManagementInventory.setItemCode(itemCode);
                        }
                    }

                    if (outBoundItemMap != null) {
                        List<MaterialAllOutboundItem> materialAllOutboundItems1 = outBoundItemMap.get(materialManagementInventory.getId());
                        if (CollectionUtils.isNotEmpty(materialAllOutboundItems1)) {
                            String itemName = materialAllOutboundItems1.stream().map(i -> i.getItemName()).collect(Collectors.toList()).stream()
                                    .collect(Collectors.joining(CommonConstant.SpecialSign.COMMA.getName()));
                            materialManagementInventory.setItemName(itemName);
                            String specification = materialAllOutboundItems1.stream().map(i -> i.getSpecification()).collect(Collectors.toList()).stream()
                                    .collect(Collectors.joining(CommonConstant.SpecialSign.COMMA.getName()));
                            if (StringUtils.isNotEmpty(specification) && !StringUtils.equals(specification, "null")) {
                                materialManagementInventory.setSpecification(specification);
                            }
                            String itemCode = materialAllOutboundItems1.stream().map(i -> i.getItemCode()).collect(Collectors.toList()).stream()
                                    .collect(Collectors.joining(CommonConstant.SpecialSign.COMMA.getName()));
                            materialManagementInventory.setItemCode(itemCode);
                        }
                    }
                    if (userMap.get(materialManagementInventory.getPreparerName()) != null) {
                        materialManagementInventory.setArrivalPersonName(userMap.get(materialManagementInventory.getPreparerName()).toString());
                        materialManagementInventory.setPreparerName(userMap.get(materialManagementInventory.getPreparerName()).toString());
                    }

                    if (materialManagementInventory.getCreateTime() != null) {
                        Integer between = Math.toIntExact(ChronoUnit.DAYS.between(materialManagementInventory.getCreateTime(), LocalDateTime.now()));
                        materialManagementInventory.setStayDay(between);
                    }

                    if (processMap != null) {
                        if (processMap.get(materialManagementInventory.getId()) != null) {
                            materialManagementInventory.setProcessId(processMap.get(materialManagementInventory.getId()).getProcessInstanceId());
                            String userId = processMap.get(materialManagementInventory.getId()).getUserId();
                            if (StringUtils.isNotEmpty(userId) && !StringUtils.equals(userId, "null")) {
                                String approveName = ApproveUserNameUtils.getApproveName(userId, userMap);
                                materialManagementInventory.setApproveUser(approveName);
                            }
                        }

                    }
                }
                return page;
            }
        }
        return null;
    }

    @Override
    public Page<MaterialManagementInventory> getBcpDullnessPage(MaterialDullnessReq materialDullnessReq) {
        List<String> allIds = new ArrayList<>();
        List<String> collectCpList = new ArrayList<>();
        LambdaQueryWrapper<MaterialCpBcpItems> materialOutWrapper = Wrappers.<MaterialCpBcpItems>lambdaQuery();
        if (StringUtils.isNotEmpty(materialDullnessReq.getItemCode())) {
            materialOutWrapper.like(MaterialCpBcpItems::getItemCode, materialDullnessReq.getItemCode());
        }
        if (StringUtils.isNotEmpty(materialDullnessReq.getItemName())) {
            materialOutWrapper.like(MaterialCpBcpItems::getItemName, materialDullnessReq.getItemName());
        }

        if (StringUtils.isNotEmpty(materialDullnessReq.getItemCode()) || StringUtils.isNotEmpty(materialDullnessReq.getItemName())
        ) {
            List<MaterialCpBcpItems> materialAllOutboundItems = materialCpBcpItemsMapper.selectList(materialOutWrapper);
            collectCpList = materialAllOutboundItems.stream().map(MaterialCpBcpItems::getCpBcpId).distinct().collect(Collectors.toList());
            allIds.addAll(collectCpList);
        }
        if (StringUtils.isNotEmpty(materialDullnessReq.getItemCode()) || StringUtils.isNotEmpty(materialDullnessReq.getItemName())) {
            if (CollectionUtils.isEmpty(collectCpList)) {
                Page<MaterialManagementInventory> page = new Page<>();
                return page;
            }

        }

        materialDullnessReq.setIds(allIds);

        MaterialWarehouseInfo one = materialWarehouseInfoService.getOne(Wrappers.<MaterialWarehouseInfo>lambdaQuery().isNotNull(MaterialWarehouseInfo::getProcessStalePeriod).gt(MaterialWarehouseInfo::getProcessStalePeriod, Constants.ZERO_INT).eq(MaterialWarehouseInfo::getWarehouseCode, MaterialWareHouseCode.BCPK_CK.getMsg()).last("limit 1"));
        if (one == null) {
            Page<MaterialManagementInventory> page = new Page<>();
            return page;
        }
        materialDullnessReq.setDullnessDay(one.getProcessStalePeriod());

        Page<MaterialManagementInventory> page = materialALLOutboundManagementMapper.getAllBCPDullnessList(new Page<MaterialManagementInventory>(materialDullnessReq.getPageNo(), materialDullnessReq.getPageSize()), materialDullnessReq);
        Map<Object, Object> userMap = redisService.hmget(RedisKey.USER_GROUP_TYPE);
        if (CollectionUtils.isEmpty(page.getRecords())) {
            return page;
        }
        List<String> businessKeys = page.getRecords().stream().map(MaterialManagementInventory::getId).collect(Collectors.toList());
        Map<String, BpmProcessInstanceStatus> processMap = null;
        //获取业务流程状态
        ResultBody<List<BpmProcessInstanceStatus>> resultBody = camundaApi.queryProcessInstanceStatus(businessKeys);
        if (resultBody != null && CollectionUtils.isNotEmpty(resultBody.getData())) {
            processMap = resultBody.getData().stream().collect(Collectors.toMap(bp -> bp.getBusinessKey(), bp -> bp, (bp1, bp2) -> bp1));
        }
        List<MaterialCpBcpItems> materialCpBcpItemsList = materialCpBcpItemsMapper.selectList(Wrappers.<MaterialCpBcpItems>lambdaQuery().in(MaterialCpBcpItems::getCpBcpId, businessKeys));
        Map<String, List<MaterialCpBcpItems>> cpBcpMap = null;
        if (CollectionUtils.isNotEmpty(materialCpBcpItemsList)) {
            cpBcpMap = materialCpBcpItemsList.stream().collect(Collectors.groupingBy(MaterialCpBcpItems::getCpBcpId));
        }

        for (MaterialManagementInventory materialManagementInventory : page.getRecords()) {
            if (cpBcpMap != null) {
                List<MaterialCpBcpItems> materialAllOutboundItems1 = cpBcpMap.get(materialManagementInventory.getId());
                if (CollectionUtils.isNotEmpty(materialAllOutboundItems1)) {
                    String itemName = materialAllOutboundItems1.stream().map(i -> i.getItemName()).collect(Collectors.toList()).stream()
                            .collect(Collectors.joining(CommonConstant.SpecialSign.COMMA.getName()));
                    materialManagementInventory.setItemName(itemName);
                    String specification = materialAllOutboundItems1.stream().map(i -> i.getSpecification()).collect(Collectors.toList()).stream()
                            .collect(Collectors.joining(CommonConstant.SpecialSign.COMMA.getName()));
                    materialManagementInventory.setSpecification(specification);
                    String itemCode = materialAllOutboundItems1.stream().map(i -> i.getItemCode()).collect(Collectors.toList()).stream()
                            .collect(Collectors.joining(CommonConstant.SpecialSign.COMMA.getName()));
                    materialManagementInventory.setItemCode(itemCode);
                }
            }
            if (userMap.get(materialManagementInventory.getPreparerName()) != null) {
                materialManagementInventory.setArrivalPersonName(userMap.get(materialManagementInventory.getPreparerName()).toString());
                materialManagementInventory.setPreparerName(userMap.get(materialManagementInventory.getPreparerName()).toString());
            }

            if (materialManagementInventory.getCreateTime() != null) {
                Integer between = Math.toIntExact(ChronoUnit.DAYS.between(materialManagementInventory.getCreateTime(), LocalDateTime.now()));
                materialManagementInventory.setStayDay(between);
            }

            if (processMap != null) {
                if (processMap.get(materialManagementInventory.getId()) != null) {
                    materialManagementInventory.setProcessId(processMap.get(materialManagementInventory.getId()).getProcessInstanceId());
                    String userId = processMap.get(materialManagementInventory.getId()).getUserId();
                    if (StringUtils.isNotEmpty(userId) && !StringUtils.equals(userId, "null")) {
                        String approveName = ApproveUserNameUtils.getApproveName(userId, userMap);
                        materialManagementInventory.setApproveUser(approveName);
                    }

                }
            }
        }
        return page;
    }

    @Override
    public Page<MaterialManagementInventory> getCpDullnessPage(MaterialDullnessReq materialDullnessReq) {
        List<String> allIds = new ArrayList<>();
        List<String> collectCpList = new ArrayList<>();
        LambdaQueryWrapper<MaterialCpBcpItems> materialOutWrapper = Wrappers.<MaterialCpBcpItems>lambdaQuery();
        if (StringUtils.isNotEmpty(materialDullnessReq.getItemCode())) {
            materialOutWrapper.like(MaterialCpBcpItems::getItemCode, materialDullnessReq.getItemCode());
        }
        if (StringUtils.isNotEmpty(materialDullnessReq.getItemName())) {
            materialOutWrapper.like(MaterialCpBcpItems::getItemName, materialDullnessReq.getItemName());
        }

        if (StringUtils.isNotEmpty(materialDullnessReq.getItemCode()) || StringUtils.isNotEmpty(materialDullnessReq.getItemName())
        ) {
            List<MaterialCpBcpItems> materialAllOutboundItems = materialCpBcpItemsMapper.selectList(materialOutWrapper);
            collectCpList = materialAllOutboundItems.stream().map(MaterialCpBcpItems::getCpBcpId).distinct().collect(Collectors.toList());
            allIds.addAll(collectCpList);
        }
        if (StringUtils.isNotEmpty(materialDullnessReq.getItemCode()) || StringUtils.isNotEmpty(materialDullnessReq.getItemName())) {
            if (CollectionUtils.isEmpty(collectCpList)) {
                Page<MaterialManagementInventory> page = new Page<>();
                return page;
            }

        }

        materialDullnessReq.setIds(allIds);

        MaterialWarehouseInfo one = materialWarehouseInfoService.getOne(Wrappers.<MaterialWarehouseInfo>lambdaQuery().isNotNull(MaterialWarehouseInfo::getProcessStalePeriod).gt(MaterialWarehouseInfo::getProcessStalePeriod, Constants.ZERO_INT).eq(MaterialWarehouseInfo::getWarehouseCode, MaterialWareHouseCode.CPK_CK.getMsg()).last("limit 1"));
        if (one == null) {
            Page<MaterialManagementInventory> page = new Page<>();
            return page;
        }
        materialDullnessReq.setDullnessDay(one.getProcessStalePeriod());
        Page<MaterialManagementInventory> page = materialALLOutboundManagementMapper.getAllCPDullnessList(new Page<MaterialManagementInventory>(materialDullnessReq.getPageNo(), materialDullnessReq.getPageSize()), materialDullnessReq);
        Map<Object, Object> userMap = redisService.hmget(RedisKey.USER_GROUP_TYPE);
        List<String> businessKeys = page.getRecords().stream().map(MaterialManagementInventory::getId).collect(Collectors.toList());
        Map<String, BpmProcessInstanceStatus> processMap = null;
        //获取业务流程状态
        ResultBody<List<BpmProcessInstanceStatus>> resultBody = camundaApi.queryProcessInstanceStatus(businessKeys);
        if (resultBody != null && CollectionUtils.isNotEmpty(resultBody.getData())) {
            processMap = resultBody.getData().stream().collect(Collectors.toMap(bp -> bp.getBusinessKey(), bp -> bp, (bp1, bp2) -> bp1));
        }
        List<MaterialCpBcpItems> materialCpBcpItemsList = materialCpBcpItemsMapper.selectList(Wrappers.<MaterialCpBcpItems>lambdaQuery().in(MaterialCpBcpItems::getCpBcpId, businessKeys));
        Map<String, List<MaterialCpBcpItems>> cpBcpMap = null;
        if (CollectionUtils.isNotEmpty(materialCpBcpItemsList)) {
            cpBcpMap = materialCpBcpItemsList.stream().collect(Collectors.groupingBy(MaterialCpBcpItems::getCpBcpId));
        }

        for (MaterialManagementInventory materialManagementInventory : page.getRecords()) {
            if (cpBcpMap != null) {
                List<MaterialCpBcpItems> materialAllOutboundItems1 = cpBcpMap.get(materialManagementInventory.getId());
                if (CollectionUtils.isNotEmpty(materialAllOutboundItems1)) {
                    String itemName = materialAllOutboundItems1.stream().map(i -> i.getItemName()).collect(Collectors.toList()).stream()
                            .collect(Collectors.joining(CommonConstant.SpecialSign.COMMA.getName()));
                    materialManagementInventory.setItemName(itemName);
                    String specification = materialAllOutboundItems1.stream().map(i -> i.getSpecification()).collect(Collectors.toList()).stream()
                            .collect(Collectors.joining(CommonConstant.SpecialSign.COMMA.getName()));
                    materialManagementInventory.setSpecification(specification);
                    String itemCode = materialAllOutboundItems1.stream().map(i -> i.getItemCode()).collect(Collectors.toList()).stream()
                            .collect(Collectors.joining(CommonConstant.SpecialSign.COMMA.getName()));
                    materialManagementInventory.setItemCode(itemCode);
                }
            }
            if (userMap.get(materialManagementInventory.getPreparerName()) != null) {
                materialManagementInventory.setArrivalPersonName(userMap.get(materialManagementInventory.getPreparerName()).toString());
                materialManagementInventory.setPreparerName(userMap.get(materialManagementInventory.getPreparerName()).toString());
            }
            if (materialManagementInventory.getCreateTime() != null) {
                Integer between = Math.toIntExact(ChronoUnit.DAYS.between(materialManagementInventory.getCreateTime(), LocalDateTime.now()));
                materialManagementInventory.setStayDay(between);
            }
            if (processMap != null) {
                if (processMap.get(materialManagementInventory.getId()) != null) {
                    materialManagementInventory.setProcessId(processMap.get(materialManagementInventory.getId()).getProcessInstanceId());
                    String userId = processMap.get(materialManagementInventory.getId()).getUserId();
                    if (StringUtils.isNotEmpty(userId) && !StringUtils.equals(userId, "null")) {
                        String approveName = ApproveUserNameUtils.getApproveName(userId, userMap);
                        materialManagementInventory.setApproveUser(approveName);
                    }
                }
            }
        }
        return page;
    }

    /**
     * @param materialDullnessReq
     * @return
     */
    public Page<MaterialManagementInventory> getWarehouseDullnessList(MaterialDullnessReq materialDullnessReq) {
        List<String> collect1 = new ArrayList<>();
        List<String> collect2 = new ArrayList<>();
        List<String> allIds = new ArrayList<>();
        LambdaQueryWrapper<MaterialAllOutboundItem> materialOutWrapper = Wrappers.<MaterialAllOutboundItem>lambdaQuery();
        if (StringUtils.isNotEmpty(materialDullnessReq.getItemCode())) {
            materialOutWrapper.like(MaterialAllOutboundItem::getItemCode, materialDullnessReq.getItemCode());
        }
        if (StringUtils.isNotEmpty(materialDullnessReq.getItemName())) {
            materialOutWrapper.like(MaterialAllOutboundItem::getItemName, materialDullnessReq.getItemName());
        }
        if (StringUtils.isNotEmpty(materialDullnessReq.getWarehouseName())) {
            materialOutWrapper.eq(MaterialAllOutboundItem::getWarehouseName, materialDullnessReq.getWarehouseName());
        }

        if (StringUtils.isNotEmpty(materialDullnessReq.getItemCode()) || StringUtils.isNotEmpty(materialDullnessReq.getItemName()) || StringUtils.isNotEmpty(materialDullnessReq.getWarehouseId())) {
            List<MaterialAllOutboundItem> materialAllOutboundItems = materialAllOutboundItemMapper.selectList(materialOutWrapper);
            collect1 = materialAllOutboundItems.stream().map(MaterialAllOutboundItem::getOutAllId).distinct().collect(Collectors.toList());
            allIds.addAll(collect1);
        }

        LambdaQueryWrapper<MaterialInventoryItem> materialInventoryItemWrapper = Wrappers.<MaterialInventoryItem>lambdaQuery();
        if (StringUtils.isNotEmpty(materialDullnessReq.getItemCode())) {
            materialInventoryItemWrapper.like(MaterialInventoryItem::getItemCode, materialDullnessReq.getItemCode());
        }
        if (StringUtils.isNotEmpty(materialDullnessReq.getItemName())) {
            materialInventoryItemWrapper.like(MaterialInventoryItem::getItemName, materialDullnessReq.getItemName());
        }
        if (StringUtils.isNotEmpty(materialDullnessReq.getWarehouseName())) {
            materialInventoryItemWrapper.eq(MaterialInventoryItem::getWarehouseName, materialDullnessReq.getWarehouseName());
        }

        if (StringUtils.isNotEmpty(materialDullnessReq.getItemCode()) || StringUtils.isNotEmpty(materialDullnessReq.getItemName()) || StringUtils.isNotEmpty(materialDullnessReq.getWarehouseName())) {
            List<MaterialInventoryItem> materialInventoryItems = materialInventoryItemMapper.selectList(materialInventoryItemWrapper);
            collect2 = materialInventoryItems.stream().map(MaterialInventoryItem::getInventoryNumber).distinct().collect(Collectors.toList());
            allIds.addAll(collect2);
        }
        if (StringUtils.isNotEmpty(materialDullnessReq.getItemCode()) || StringUtils.isNotEmpty(materialDullnessReq.getItemName()) || StringUtils.isNotEmpty(materialDullnessReq.getWarehouseName())) {
            if (CollectionUtils.isEmpty(collect1) && CollectionUtils.isEmpty(collect2)) {
                Page<MaterialManagementInventory> page = new Page<>();
                return page;
            }
        }
        materialDullnessReq.setIds(allIds);
        Page<MaterialManagementInventory> page = materialALLOutboundManagementMapper.getWarehouseDullnessList(new Page<MaterialManagementInventory>(materialDullnessReq.getPageNo(), materialDullnessReq.getPageSize()), materialDullnessReq);
        if (CollectionUtils.isEmpty(page.getRecords())) {
            return page;
        }
        Map<Object, Object> userMap = redisService.hmget(RedisKey.USER_GROUP_TYPE);
        List<String> businessKeys = page.getRecords().stream().map(MaterialManagementInventory::getId).collect(Collectors.toList());
        Map<String, BpmProcessInstanceStatus> processMap = null;
        //获取业务流程状态
        ResultBody<List<BpmProcessInstanceStatus>> resultBody = camundaApi.queryProcessInstanceStatus(businessKeys);
        if (resultBody != null && CollectionUtils.isNotEmpty(resultBody.getData())) {
            processMap = resultBody.getData().stream().collect(Collectors.toMap(bp -> bp.getBusinessKey(), bp -> bp, (bp1, bp2) -> bp1));
        }

        // 获取出入库物料名称 编号 规格型号
        List<String> idList = page.getRecords().stream().map(MaterialManagementInventory::getId).collect(Collectors.toList());
        List<MaterialAllOutboundItem> materialAllOutboundItems = materialAllOutboundItemMapper.selectList(Wrappers.<MaterialAllOutboundItem>lambdaQuery().in(MaterialAllOutboundItem::getOutAllId, idList));
        List<String> numberList = page.getRecords().stream().map(MaterialManagementInventory::getNumber).collect(Collectors.toList());
        List<MaterialInventoryItem> materialInventoryItems = materialInventoryItemMapper.selectList(Wrappers.<MaterialInventoryItem>lambdaQuery().in(MaterialInventoryItem::getInventoryNumber, numberList));

        Map<String, List<MaterialInventoryItem>> itemMap = null;
        if (CollectionUtils.isNotEmpty(materialInventoryItems)) {
            itemMap = materialInventoryItems.stream().collect(Collectors.groupingBy(MaterialInventoryItem::getInventoryNumber));
        }
        Map<String, List<MaterialAllOutboundItem>> outBoundItemMap = null;
        if (CollectionUtils.isNotEmpty(materialAllOutboundItems)) {
            outBoundItemMap = materialAllOutboundItems.stream().collect(Collectors.groupingBy(MaterialAllOutboundItem::getOutAllId));
        }
        for (MaterialManagementInventory materialManagementInventory : page.getRecords()) {
            if (itemMap != null) {
                List<MaterialInventoryItem> items = itemMap.get(materialManagementInventory.getNumber());
                if (CollectionUtils.isNotEmpty(items)) {
                    String itemName = items.stream().map(i -> i.getItemName()).collect(Collectors.toList()).stream()
                            .collect(Collectors.joining(CommonConstant.SpecialSign.COMMA.getName()));
                    materialManagementInventory.setItemName(itemName);
                    String specification = items.stream().map(i -> i.getSpecificationModel()).collect(Collectors.toList()).stream()
                            .collect(Collectors.joining(CommonConstant.SpecialSign.COMMA.getName()));

                    String wareHouseName = items.stream().map(i -> i.getWarehouseName()).collect(Collectors.toList()).stream()
                            .collect(Collectors.joining(CommonConstant.SpecialSign.COMMA.getName()));
                    materialManagementInventory.setWarehouseName(wareHouseName);
                    if (StringUtils.isNotEmpty(specification) && !StringUtils.equals(specification, "null")) {
                        materialManagementInventory.setSpecification(specification);
                    }

                    String itemCode = items.stream().map(i -> i.getItemCode()).collect(Collectors.toList()).stream()
                            .collect(Collectors.joining(CommonConstant.SpecialSign.COMMA.getName()));
                    materialManagementInventory.setItemCode(itemCode);
                }
            }
            if (outBoundItemMap != null) {
                List<MaterialAllOutboundItem> materialAllOutboundItems1 = outBoundItemMap.get(materialManagementInventory.getId());
                if (CollectionUtils.isNotEmpty(materialAllOutboundItems1)) {
                    String itemName = materialAllOutboundItems1.stream().map(i -> i.getItemName()).collect(Collectors.toList()).stream()
                            .collect(Collectors.joining(CommonConstant.SpecialSign.COMMA.getName()));
                    materialManagementInventory.setItemName(itemName);
                    String specification = materialAllOutboundItems1.stream().map(i -> i.getSpecification()).collect(Collectors.toList()).stream()
                            .collect(Collectors.joining(CommonConstant.SpecialSign.COMMA.getName()));
                    if (StringUtils.isNotEmpty(specification) && !StringUtils.equals(specification, "null")) {
                        materialManagementInventory.setSpecification(specification);
                    }
                    String wareHouseName = materialAllOutboundItems1.stream().map(i -> i.getWarehouseName()).collect(Collectors.toList()).stream()
                            .collect(Collectors.joining(CommonConstant.SpecialSign.COMMA.getName()));
                    materialManagementInventory.setWarehouseName(wareHouseName);

                    String itemCode = materialAllOutboundItems1.stream().map(i -> i.getItemCode()).collect(Collectors.toList()).stream()
                            .collect(Collectors.joining(CommonConstant.SpecialSign.COMMA.getName()));
                    materialManagementInventory.setItemCode(itemCode);
                }
            }
            if (userMap.get(materialManagementInventory.getPreparerName()) != null) {
                materialManagementInventory.setArrivalPersonName(userMap.get(materialManagementInventory.getPreparerName()).toString());
                materialManagementInventory.setPreparerName(userMap.get(materialManagementInventory.getPreparerName()).toString());
            }

            if (materialManagementInventory.getCreateTime() != null) {
                Integer between = Math.toIntExact(ChronoUnit.DAYS.between(materialManagementInventory.getCreateTime(), LocalDateTime.now()));
                materialManagementInventory.setStayDay(between);
            }
            if (processMap != null) {
                if (processMap.get(materialManagementInventory.getId()) != null) {
                    materialManagementInventory.setProcessId(processMap.get(materialManagementInventory.getId()).getProcessInstanceId());
                    String userId = processMap.get(materialManagementInventory.getId()).getUserId();
                    if (StringUtils.isNotEmpty(userId) && !StringUtils.equals(userId, "null")) {
                        String approveName = ApproveUserNameUtils.getApproveName(userId, userMap);
                        materialManagementInventory.setApproveUser(approveName);
                    }
                }
                if (materialManagementInventory.getCreateTime() != null) {
                    Integer between = Math.toIntExact(ChronoUnit.DAYS.between(materialManagementInventory.getCreateTime(), LocalDateTime.now()));
                    materialManagementInventory.setStayDay(between);
                }
            }
        }
        return page;
    }

    @Override
    public Page<MaterialRqDullnessDTO> getRqDullnessList(MaterialRQDullnessReq materialRQDullnessReq) {
        Page<MaterialRqDullnessDTO> rqDullnessList = materialALLOutboundManagementMapper.getRqDullnessList(new Page<MaterialRqDullnessDTO>(materialRQDullnessReq.getPageNo(), materialRQDullnessReq.getPageSize()), materialRQDullnessReq);
        return rqDullnessList;
    }

    @Override
    public Page<MaterialDullnessDTO> getMaterialDullnessList(MaterialDullnessReq materialDullnessReq) {
        Page<MaterialDullnessDTO> materialDullnessList = materialALLOutboundManagementMapper.getMaterialDullnessList(new Page<MaterialDullnessDTO>(materialDullnessReq.getPageNo(), materialDullnessReq.getPageSize()), materialDullnessReq);
        return materialDullnessList;
    }


    @Override
    public void updateGD(MaterialManagementInventory materialManagementInventory) {
        // 更改流程状态
        for (MaterialWareHouseInTableNameCode ele : MaterialWareHouseInTableNameCode.values()) {
            if (materialManagementInventory.getWarehouseCode().equals(ele.getCode())) {
                String tableName = ele.getMsg();
                materialALLOutboundManagementMapper.updateOutStatus(tableName, materialManagementInventory.getId());
            }
        }
        MaterialALLOutboundManagement materialALLOutboundManagement = materialALLOutboundManagementMapper.selectById(materialManagementInventory.getId());
        if (materialALLOutboundManagement != null) {
            materialALLOutboundManagement.setFinishDate(LocalDateTime.now());
            materialALLOutboundManagement.setOutStatus(Constants.TWO_STR);
            materialALLOutboundManagement.setApproveStatus(Constants.TWO_STR);
            materialALLOutboundManagementMapper.updateById(materialALLOutboundManagement);
            List<MaterialAllOutboundItem> materialAllOutboundItems = materialAllOutboundItemMapper.selectList(Wrappers.<MaterialAllOutboundItem>lambdaQuery().eq(MaterialAllOutboundItem::getOutAllId, materialALLOutboundManagement.getId()));
            for (MaterialAllOutboundItem materialAllOutboundItem : materialAllOutboundItems) {
                if (materialAllOutboundItem.getWarehouseCode().equals(MaterialWareHouseCode.YCLK_CK.getMsg())) {
                    MaterialALLInventoryManagement one = materialInventoryManagementService.getOne(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
                            .eq(MaterialALLInventoryManagement::getBatchNumber, materialAllOutboundItem.getBatchNumber())
                            .eq(MaterialALLInventoryManagement::getBarcodeNumber, materialAllOutboundItem.getBarcodeNumber())
                            .eq(MaterialALLInventoryManagement::getMaterialCode, materialAllOutboundItem.getItemCode())
                            .eq(MaterialALLInventoryManagement::getStorageLocation, materialAllOutboundItem.getStorageLocationId())
                            .eq(MaterialALLInventoryManagement::getWareHouseCode, MaterialWareHouseCode.YCLK_CK.getMsg())
                            .last("limit 1")
                    );
                    if (one != null) {
                        BigDecimal subtract = one.getFrozenQuantity().subtract(materialAllOutboundItem.getQuantity());
                        one.setFrozenQuantity(subtract);
                        BigDecimal add = one.getAvailableQuantity().add(materialAllOutboundItem.getQuantity());
                        one.setAvailableQuantity(add);
                        materialInventoryManagementService.updateById(one);
                    }

                } else {
                    MaterialALLInventoryManagement one = materialInventoryManagementService.getOne(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
                            .eq(MaterialALLInventoryManagement::getMaterialCode, materialAllOutboundItem.getItemCode())
                            .eq(MaterialALLInventoryManagement::getStorageLocation, materialAllOutboundItem.getStorageLocationId())
                            .eq(MaterialALLInventoryManagement::getWareHouseCode, materialAllOutboundItem.getWarehouseCode())
                            .last("limit 1"));
                    BigDecimal subtract = one.getFrozenQuantity().subtract(materialAllOutboundItem.getQuantity());
                    one.setFrozenQuantity(subtract);
                    BigDecimal add = one.getAvailableQuantity().add(materialAllOutboundItem.getQuantity());
                    one.setAvailableQuantity(add);
                    materialInventoryManagementService.updateById(one);
                }
            }
        }

    }

    @Override
    public void updateBCPGD(MaterialManagementInventory materialManagementInventory) {
        MaterialBcpProductsOut materialBcpProductsOut = materialBcpProductsOutMapper.selectById(materialManagementInventory.getId());
        if (materialBcpProductsOut != null) {
            materialBcpProductsOut.setFinishTime(LocalDateTime.now());
            materialBcpProductsOut.setOutStatus(Constants.TWO_STR);
            materialBcpProductsOut.setApproveStatus(Constants.TWO_STR);
            materialBcpProductsOutMapper.updateById(materialBcpProductsOut);
            List<MaterialCpBcpItems> materialCpBcpItemsList = materialCpBcpItemsMapper.selectList(Wrappers.<MaterialCpBcpItems>lambdaQuery().eq(MaterialCpBcpItems::getCpBcpId, materialBcpProductsOut.getId()));
            for (MaterialCpBcpItems materialCpBcpItems : materialCpBcpItemsList) {
                List<MaterialALLInventoryManagement> list = materialInventoryManagementService.list(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
                        .eq(MaterialALLInventoryManagement::getWareHouseCode, MaterialWareHouseCode.CPK_CK)
                        .eq(MaterialALLInventoryManagement::getATypeShelf,materialCpBcpItems.getATypeShelf())
                        .isNotNull(MaterialALLInventoryManagement::getFrozenQuantity)
                        .gt(MaterialALLInventoryManagement::getStockQuantity, Constants.ZERO_INT)
                );
                for (MaterialALLInventoryManagement materialALLInventoryManagement : list) {
                    materialALLInventoryManagement.setFrozenQuantity(null);
                    materialInventoryManagementService.updateById(materialALLInventoryManagement);
                }

            }
        }
        MaterialBcpProductsInInfo materialBcpProductsInInfo = materialBcpProductsInInfoMapper.selectById(materialManagementInventory.getId());
        if (materialBcpProductsInInfo != null) {
            materialBcpProductsInInfo.setFinishDate(LocalDateTime.now());
            materialBcpProductsInInfo.setInStatus(Constants.TWO_STR);
            materialBcpProductsInInfo.setApproveStatus(Constants.TWO_STR);
            materialBcpProductsInInfoMapper.updateById(materialBcpProductsInInfo);

        }
    }

    @Override
    public void updateCPGD(MaterialManagementInventory materialManagementInventory) {
        MaterialCPProductsOut materialCPProductsOut = materialCpProductsOutMapper.selectById(materialManagementInventory.getId());
        if (materialCPProductsOut != null) {
            materialCPProductsOut.setFinishTime(LocalDateTime.now());
            materialCPProductsOut.setOutStatus(Constants.TWO_STR);
            materialCPProductsOut.setApproveStatus(Constants.TWO_STR);
            materialCpProductsOutMapper.updateById(materialCPProductsOut);
            List<MaterialCpBcpItems> materialCpBcpItemsList = materialCpBcpItemsMapper.selectList(Wrappers.<MaterialCpBcpItems>lambdaQuery().eq(MaterialCpBcpItems::getCpBcpId, materialCPProductsOut.getId()));
            for (MaterialCpBcpItems materialCpBcpItems : materialCpBcpItemsList) {
                List<MaterialALLInventoryManagement> list = materialInventoryManagementService.list(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
                        .eq(MaterialALLInventoryManagement::getWareHouseCode, MaterialWareHouseCode.BCPK_CK)
                        .eq(MaterialALLInventoryManagement::getATypeShelf,materialCpBcpItems.getATypeShelf())
                        .isNotNull(MaterialALLInventoryManagement::getFrozenQuantity)
                        .gt(MaterialALLInventoryManagement::getStockQuantity, Constants.ZERO_INT)
                );
                for (MaterialALLInventoryManagement materialALLInventoryManagement : list) {
                    materialALLInventoryManagement.setFrozenQuantity(null);
                    materialInventoryManagementService.updateById(materialALLInventoryManagement);
                }
            }
        }
        MaterialCPProductsInInfo materialCPProductsInInfo = materialCPProductsInInfoMapper.selectById(materialManagementInventory.getId());
        if (materialCPProductsInInfo != null) {
            materialCPProductsInInfo.setFinishDate(LocalDateTime.now());
            materialCPProductsInInfo.setInStatus(Constants.TWO_STR);
            materialCPProductsInInfo.setApproveStatus(Constants.TWO_STR);
            materialCPProductsInInfoMapper.updateById(materialCPProductsInInfo);
        }
    }

}
